/**********************************************************************
* Filename: Jogo.java
* Created: 2012/04/30
* @author Fernando Brito e Abreu
**********************************************************************/
package org.bunny.businessLayer;

import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.SortedSet;
import java.util.TreeSet;

public class Jogo{
	public static Set<Jogo> allInstances = new HashSet<Jogo>();
	
	private CalendarDate dia;
	private String hora;
	private Grupo grupo;
	private Estadio estadio;
	
	/**********************************************************************
	* Default constructor
	**********************************************************************/
	public Jogo(){
		allInstances.add(this);
	}
	
	/**********************************************************************
	* Parameterized constructor
	* @param dia the dia to initialize
	* @param hora the hora to initialize
	* @param grupo the grupo to initialize
	* @param estadio the estadio to initialize
	**********************************************************************/
	public Jogo(CalendarDate dia, String hora, Grupo grupo, Estadio estadio){
		this.dia = dia;
		this.hora = hora;
		this.grupo = grupo;
		this.estadio = estadio;
		allInstances.add(this);
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the dia of the jogo
	**********************************************************************/
	public CalendarDate dia(){
		return dia;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param dia the dia to set
	**********************************************************************/
	public void setDia(CalendarDate dia){
		this.dia = dia;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the hora of the jogo
	**********************************************************************/
	public String hora(){
		return hora;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param hora the hora to set
	**********************************************************************/
	public void setHora(String hora){
		this.hora = hora;
	}
	
	/**********************************************************************
	* ONE2MANY getter for Jogo[*] <-> Grupo[1]
	* @return the grupo of the jogo
	**********************************************************************/
	public Grupo grupo(){
		return grupo;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Jogo[*] <-> Grupo[1]
	* @param grupo the grupo to set
	**********************************************************************/
	public void setGrupo(Grupo grupo){
		this.grupo = grupo;
	}
	
	/**********************************************************************
	* ONE2MANY getter for Jogo[*] <-> Estadio[1]
	* @return the estadio of the jogo
	**********************************************************************/
	public Estadio estadio(){
		return estadio;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Jogo[*] <-> Estadio[1]
	* @param estadio the estadio to set
	**********************************************************************/
	public void setEstadio(Estadio estadio){
		this.estadio = estadio;
	}
	
	/**********************************************************************
	* MEMBER2ASSOCIATIVE getter for Jogo[*] <-> Equipa[2] ordered
	* @return the equipa of the jogo
	**********************************************************************/
	public List<Equipa> equipa(){
		List<Equipa> result = new LinkedList<Equipa>();
		for (Equipa x : Equipa.allInstances){
			if (x.jogo()  ==  this)
				result.add(x);
		}
		return result;
	}
	
	/**********************************************************************
	* MEMBER2ASSOCIATIVE setter for Jogo[*] <-> Equipa[2] ordered
	* @param equipa the equipa to set
	**********************************************************************/
	public void setEquipa(List<Equipa> equipa){
		for (Equipa x : equipa){
			x.setJogo(this);
		}
	}
	
	/**********************************************************************
	* MEMBER2MEMBER getter for Jogo[*] <-> Pais[2] ordered
	* @return the seleccao of the jogo
	**********************************************************************/
	public List<Pais> seleccao(){
		List<Pais> result = new LinkedList<Pais>();
		for (Equipa x : Equipa.allInstances){
			if (x.jogo()  ==  this)
				result.add(x.seleccao());
		}
		return result;
	}
	
	/**********************************************************************
	* MEMBER2MEMBER setter for Jogo[*] <-> Pais[2] ordered
	* @param seleccao the seleccao to set
	**********************************************************************/
	public void setSeleccao(List<Pais> seleccao){
		for (Pais t : seleccao){
			for (Equipa x: Equipa.allInstances){
				if (x.jogo() == this)
					x.setSeleccao(t);
			}
		}
	}
	
//	/**********************************************************************
//	* User-defined operation specified in SOIL/OCL
//	* @param data the data to set
//	* @param hora the hora to set
//	* @param visitado the visitado to set
//	* @param visitante the visitante to set
//	* @param estadio the estadio to set
//	* @param grupo the grupo to set
//	**********************************************************************/
//	public void inicializa(String data, String hora, Pais visitado, Pais visitante, Estadio estadio, Grupo grupo){
//		//	TODO
//		//	dummy := new CalendarDate;
//		//	 self.dia := dummy.stringToDate(data);
//		//	 destroy dummy;
//		//	 self.hora := hora;
//		//	 if visitado.isDefined then new Equipa between (visitado,self) end;
//		//	 if visitante.isDefined then new Equipa between (visitante,self) end;
//		//	 insert (estadio,self) into Estadio_Jogo;
//		//	 insert (grupo,self) into Grupo_Jogo;
//	}
	
	//	PRE-CONDITIONS (TODO)
	/*
	pre JogoParametrosDefinidos
		((((data.isDefined and hora.isDefined) and visitado.isDefined) and estadio.isDefined) and grupo.isDefined)
	
	*/
	
	//	POST-CONDITIONS (TODO)
	/*
	post JogoInicializado
		((self.dia.isDefined and self.hora.isDefined) and (self.seleccao->includes(visitado) and self.seleccao->includes(visitante)))
	
	*/
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param data the data to set
	* @param hora the hora to set
	* @param visitado the visitado to set
	* @param visitante the visitante to set
	* @param estadio the estadio to set
	* @param grupo the grupo to set
	**********************************************************************/
//	public void inicializaComCD(CalendarDate data, String hora, Pais visitado, Pais visitante, Estadio estadio, Grupo grupo)
//	{
//		//	TODO
//		//	self.dia := data;
//		//	 self.hora := hora;
//		//	 equipavisit := new Equipa between (visitado,self);
//		//	 equipavisitan := new Equipa between (visitante,self);
//		//	 insert (estadio,self) into Estadio_Jogo;
//		//	 insert (grupo,self) into Grupo_Jogo;
//		//	 setEquipas := Set {equipavisit}->union(Set {equipavisitan});
//		//	 for eq in setEquipas do for j in eq.jogador do membro := new Membro between (j,eq);
//		//	 if (j.data_nascimento.isLeap() and ((j.data_nascimento.month = 3) or (j.data_nascimento.month = 9))) then cartaoA := new Cartao;
//		//	 cartaoA.inicializa(TipoCartao::Amarelo, (j.data_nascimento.day + j.data_nascimento.month));
//		//	 membro.inicializa(0, 90);
//		//	 insert (membro,cartaoA) into Membro_Cartao end;
//		//	 if ((j.data_nascimento.isLeap() and (j.data_nascimento.month = 3)) and (j.data_nascimento.day > 15)) then cartaoV := new Cartao;
//		//	 cartaoV.inicializa(TipoCartao::Vermelho, ((j.data_nascimento.day * 2) + j.data_nascimento.month));
//		//	 membro.inicializa(0, 70);
//		//	 insert (membro,cartaoV) into Membro_Cartao end;
//		//	 if (((j.data_nascimento.month > 7) and (j.data_nascimento.day < 15)) and (j.posicao = PosicaoJogador::Avancado)) then golo := new Golo;
//		//	 golo.inicializa(if j.data_nascimento.isLeap() then (j.data_nascimento.month * 7) else j.data_nascimento.day endif);
//		//	 membro.inicializa(0, 90);
//		//	 insert (membro,golo) into Membro_Golo end end end;
//	}
	
	//	PRE-CONDITIONS (TODO)
	/*
	pre JogoParametrosDefinidos2
		((((data.isDefined and hora.isDefined) and visitado.isDefined) and estadio.isDefined) and grupo.isDefined)
	
	*/
	
	//	POST-CONDITIONS (TODO)
	/*
	post JogoInicializado2
		((self.dia.isDefined and self.hora.isDefined) and (self.seleccao->includes(visitado) and self.seleccao->includes(visitante)))
	
	*/
	
	/* (non-Javadoc)
	* @see java.lang.Object#toString()
	*/
	@Override
	/**********************************************************************
	* Object serializer
	**********************************************************************/
	public String toString()
	{
		return "Jogo [dia=" + dia + ", hora=" + hora + ", grupo=" + grupo + ", estadio=" + estadio + "]\n";
	}
	
	//	-------------------------------------------------------------------------------
	//	INVARIANTS (TODO)
	/*
	inv VisitadoDiferenteVisitante
		(self.seleccao->asSet->size = 2)
	
	*/
}
